﻿using Abp.Application.Services.Dto;
using Abp.AutoMapper;
using Abp.Collections.Extensions;
using Abp.Domain.Repositories;
using Abp.Extensions;
using Abp.Linq.Extensions;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text;
using System.Threading.Tasks;
using Yq.BookList.BookListManagement.Books.Dtos;

namespace Yq.BookList.BookListManagement.Books
{
    /// <summary>
    /// 书籍的应用层服务
    /// </summary>
    public class BookAppService : BookListAppServiceBase, IBookAppService
    {
        private readonly IRepository<Book, long> _bookRepository;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="bookRepository"></param>
        public BookAppService(IRepository<Book, long> bookRepository)
        {
            _bookRepository = bookRepository;
        }

        /// <summary>
        /// 分页获取查询书籍的功能
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<BookListDto>> GetPageBook(GetBookInput input)
        {
            var query = _bookRepository.GetAll().AsNoTracking().WhereIf(
                !input.FilterText.IsNullOrWhiteSpace(), a => a.BookName.Contains(input.FilterText)
                );
            var count = await query.CountAsync();

            var entityList = await query.OrderBy(input.Sorting).PageBy(input).ToListAsync();

            //autoMapper
            var entityListDtos = entityList.MapTo<List<BookListDto>>();

            //定义AutoMapper

            return new PagedResultDto<BookListDto>(count, entityListDtos);
        }

        /// <summary>
        /// 添加或修改书籍信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task CreateOrUpdateBook(CreateOrUpdateBookInput input)
        {
            if(input.Book.Id.HasValue)
            {
                //修改
                await UpdateBook(input.Book);
            }
            else
            {
                //添加
                await CreateBook(input.Book);
            }
        }

        /// <summary>
        /// 创建
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        protected virtual async Task<BookEditDto> CreateBook(BookEditDto input)
        {
            //不能单元测试
            var entity = input.MapTo<Book>();
            await _bookRepository.InsertAsync(entity);
            var dto = entity.MapTo<BookEditDto>();
            return dto;
            //可以单元测试
            //var model = ObjectMapper.Map<Book>(input);
            //var oo = ObjectMapper.Map(input, entity);
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        protected virtual async Task UpdateBook(BookEditDto input)
        {
            var entity = await _bookRepository.GetAsync(input.Id.Value);
            input.MapTo(entity);
            await _bookRepository.UpdateAsync(entity);

        }

        /// <summary>
        /// 删除书籍
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task DeleteBook(EntityDto<long> input)
        {
            await _bookRepository.DeleteAsync(input.Id);
        }


        /// <summary>
        /// 批量删除书籍
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task BatchDeleteBooks(List<long> input)
        {
            await _bookRepository.DeleteAsync(a => input.Contains(a.Id));
        }

        /// <summary>
        /// 获取编辑状态下的Book实体
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<GetBookForEditOutput> GetForEditBook(NullableIdDto<long> input)
        {
            var output = new GetBookForEditOutput();

            BookEditDto dto;

            if(input.Id.HasValue)
            {
                var entity = await _bookRepository.GetAsync(input.Id.Value);

                dto = entity.MapTo<BookEditDto>();

            }
            else
            {
                dto = new BookEditDto();
            }
            output.book = dto;
            return output;
        }
    }
}
